package com.soccertgc
{
	public class Version
	{
		
		// -------------------------------------------------------------------------------
		// CONSTANTS
		// -------------------------------------------------------------------------------
		
		// Separators string
		protected static const 	SEPARATOR:String						= ".";
		protected static const 	SEPARATOR_DESCRIPTION:String			= " ";
		
		protected static const 	CODENAME_HEADER:String					= "[codename:";
		protected static const 	CODENAME_FOOTER:String					= "]";
		
		// Default values
		protected static const 	DEFAULT_MAJOR:int						= 1;
		protected static const 	DEFAULT_MINOR:int						= 0;
		protected static const 	DEFAULT_REVISION:int					= 0;
		protected static const 	DEFAULT_BUILD:String					= "";
		protected static const 	DEFAULT_TYPE:VersionType				= VersionType.RELEASE;
		protected static const 	DEFAULT_CODENAME:String					= "";		
		
		// Invalid values
		protected static const 	INVALID_MAJOR:int						= -1;
		protected static const 	INVALID_MINOR:int						= -1;
		protected static const 	INVALID_REVISION:int					= -1;
		protected static const	INVALID_BUILD:String					= "";
		protected static const	INVALID_CODENAME:String					= "";
		
		// Invalid version, used to initialize unknown version variables
		public static const		INVALID:Version = new Version(VersionType.RELEASE, INVALID_MAJOR, INVALID_MINOR, INVALID_REVISION, INVALID_BUILD);
		
		// -------------------------------------------------------------------------------
		// FIELDS
		// -------------------------------------------------------------------------------
		
		private var _major:int;
		private var _minor:int;
		private var _revision:int;
		private var _build:String;
		private var _type:VersionType;
		private var _codename:String;
		
		// -------------------------------------------------------------------------------
		// CONSTRUCTORS
		// -------------------------------------------------------------------------------
		
		public function Version(type:VersionType, major:int = DEFAULT_MAJOR, minor:int = DEFAULT_MINOR, revision:int = DEFAULT_REVISION, build:String = DEFAULT_BUILD, codename:String = DEFAULT_CODENAME)
		{
			_type	  = type;
			_major 	  = major;
			_minor 	  = minor;
			_revision = revision;
			_build 	  = build;
			_codename = codename;
		}
		
		// -------------------------------------------------------------------------------
		// PROPERTIES
		// -------------------------------------------------------------------------------

		public function get major():int
		{
			return _major;
		}
		
		protected function set major(value:int):void
		{
			_major = value;
		}
		
		public function get minor():int
		{
			return _minor;
		}
		
		protected function set minor(value:int):void
		{
			_minor = value;
		}
		
		public function get revision():int
		{
			return _revision;
		}
		
		protected function set revision(value:int):void
		{
			_revision = value;
		}
		
		public function get build():String
		{
			return _build;
		}
		
		protected function set build(value:String):void
		{
			_build = value;
		}
		
		public function get type():VersionType
		{
			return _type;
		}
		
		protected function set type(value:VersionType):void
		{
			_type = value;
		}
		
		public function get codename():String
		{
			return _codename;
		}
		
		public function get isValid():Boolean
		{
			return	_major != INVALID_MAJOR &&
					_minor != INVALID_MINOR;
		}
		
		// -------------------------------------------------------------------------------
		// PRIVATE METHODS
		// -------------------------------------------------------------------------------
		
		// -------------------------------------------------------------------------------
		// PUBLIC METHODS
		// -------------------------------------------------------------------------------
				
		public function toString():String
		{
			var output:String = "";
			// Check if the version is valid
			if (isValid)
			{
				output += _major + SEPARATOR + _minor;
				if (_revision != INVALID_REVISION) 	output += SEPARATOR + _revision;
				if (_build != INVALID_BUILD) 		output += SEPARATOR + _build;
				if (_type != VersionType.RELEASE) 	output += SEPARATOR_DESCRIPTION + _type.sign;
				if (_codename != INVALID_CODENAME) 	output += SEPARATOR_DESCRIPTION +
															  CODENAME_HEADER +
															  _codename +
															  CODENAME_FOOTER;
			}
			else
			{
				output = "<invalid version>";
			}
			return output;
		}
		
		// -------------------------------------------------------------------------------
		// STATIC METHODS
		// -------------------------------------------------------------------------------
		
		/**
		 * 
		 * @param data
		 * @return 
		 * 
		 */		
		public static function parse(data:String):Version
		{
			// Tokens
			var tokens:Array = data.split(SEPARATOR);
			// Default vars
			var major:int 	 = INVALID_MAJOR;
			var minor:int 	 = INVALID_MINOR;
			var revision:int = INVALID_REVISION;
			var build:String = INVALID_BUILD;
			var type:VersionType = VersionType.RELEASE; 
			// Check major token
			if (tokens.length > 0 && !isNaN(Number(tokens[0])))
			{
				major = int(tokens[0]);
				// Check minor token
				if (tokens.length > 1 && !isNaN(Number(tokens[1])))
				{
					major = int(tokens[1]);
					// Check revision token
					if (tokens.length > 2 && !isNaN(Number(tokens[2])))
					{
						revision = int(tokens[2]);
						// Check desc token
						if (tokens.length > 3)
						{
							var desc:String = tokens[3]; 
							if (desc.indexOf(SEPARATOR_DESCRIPTION) > 0)
							{
								// Split the description
								var descs:Array = desc.split(SEPARATOR_DESCRIPTION);
								// Builds
								build = descs[0];
								type  = VersionType.getBySign(descs[1]);
							}
							else
							{
								build = desc;
								type = VersionType.RELEASE;
							}
						}
					}
				}
			}
			// Creates the new version
			return new Version(type, major, minor, revision, build);
		}		

	}
}